local fs = require "nixio.fs"

local sslocal =(luci.sys.call("pidof ss-local > /dev/null") == 0)
local ssredir =(luci.sys.call("pidof ss-redir > /dev/null") == 0)
if ssredir then
	m = Map("shadowsocks", translate("ShadowSocks"), translate("ShadowSocks is running ( Redir )"))
elseif sslocal then
	m = Map("shadowsocks", translate("ShadowSocks"), translate("ShadowSocks is running ( Socks5 )"))
else
	m = Map("shadowsocks", translate("ShadowSocks"), translate("ShadowSocks is not running"))
end

server = m:section(TypedSection, "shadowsocks", translate("Server Setting"))
server.anonymous = true

enabled = server:option(ListValue, "enabled", translate("Run as"))
enabled:value("0", "Disable")
enabled:value("1", "Redir")
enabled:value("2", "Socks5")
enabled.default = "table"
enabled.rmempty = false

server_host = server:option(Value, "server_host", translate("Server Host"))
server_host.datatype = "host"
server_host.default = "127.0.0.1"
server_host.rmempty = false

server_port = server:option(Value, "server_port", translate("Server Port"))
server_port.datatype = "port"
server_port.default = "1080"
server_port.rmempty = false

password = server:option(Value, "password", translate("Password"))
password.password = true
password.default = "password"
password.rmempty = false

encrypt_method = server:option(ListValue, "encrypt_method", translate("Encrypt Method"))
encrypt_method:value("table")
encrypt_method:value("rc4")
encrypt_method:value("rc4-md5")
encrypt_method:value("aes-128-cfb")
encrypt_method:value("aes-192-cfb")
encrypt_method:value("aes-256-cfb")
encrypt_method:value("bf-cfb")
encrypt_method:value("cast5-cfb")
encrypt_method:value("des-cfb")
encrypt_method:value("camellia-128-cfb")
encrypt_method:value("camellia-192-cfb")
encrypt_method:value("camellia-256-cfb")
encrypt_method:value("idea-cfb")
encrypt_method:value("rc2-cfb")
encrypt_method:value("seed-cfb")
encrypt_method:value("salsa20")
encrypt_method:value("chacha20")
encrypt_method.default = "table"
encrypt_method.rmempty = false

timeout = server:option(Value, "timeout", translate("Timeout"))
timeout.datatype = "uinteger"
timeout.default = "60"
timeout.rmempty = false

tcp_fast_open_enabled = server:option(Flag, "tcp_fast_open_enabled", translate("TCP Fast Open"))
tcp_fast_open_enabled.default = "0"
tcp_fast_open_enabled.rmempty = false

r = m:section(TypedSection, "shadowsocks", translate("Redir"))
r.anonymous = true

redir = r:tab("redir", translate("General"))

redir_port = r:taboption("redir", Value, "redir_port", translate("Local Port"))
redir_port.datatype = "port"
redir_port.default = "10086"
redir_port.rmempty = false

redir_model = r:taboption("redir", ListValue, "redir_model", translate("Proxy Mode"))
redir_model:value("0", translate("Global"))
redir_model:value("1", translate("Ignore IP"))
redir_model:value("2",translate("Specify IP"))
redir_model:value("3", translate("Domain"))
redir_model.default = "1"
redir_model.rmempty = false


-- Mode: Ignore
redir_ignore = r:tab("ignore", translate("Ignore IP"))
ignore_china = r:taboption("ignore", Flag, "ignore_china", translate("China IP List"), "/etc/ipset/china")
ignore_china.default = "1"
ignore_china.rmempty = false
ignore_china:depends("redir_model", "1")
ignore_user = r:taboption("ignore", TextValue, "ignore_user", "User Ignore IP")
ignore_user.template = "cbi/tvalue"
ignore_user.size = 30
ignore_user.rows = 5
ignore_user.wrap = "off"
ignore_user:depends("redir_model", "1")
function ignore_user.cfgvalue(self, section)
	return fs.readfile("/etc/ipset/ignore") or ""
end
function ignore_user.write(self, section, value)
	if value then
		value = value:gsub("\r\n?", "\n")
		fs.writefile("/tmp/ignore", value)
		fs.mkdirr("/etc/ipset")
		if (fs.access("/etc/ipset/ignore") ~= true or luci.sys.call("cmp -s /tmp/ignore /etc/ipset/ignore") == 1) then
			fs.writefile("/etc/ipset/ignore", value)
		end
		fs.remove("/tmp/ignore")
	end
end


-- Mode: Specify
redir_specify = r:tab("specify", translate("Specify IP"))
specify_gfw = r:taboption("specify", Flag, "specify_gfw", translate("GFW IP List"), "/etc/ipset/gfw")
specify_gfw.default = "1"
specify_gfw.rmempty = false
specify_gfw:depends("redir_model", "2")
specify_user = r:taboption("specify", TextValue, "specify_user", translate("User Specify IP"))
specify_user.template = "cbi/tvalue"
specify_user.size = 30
specify_user.rows = 10
specify_user.wrap = "off"
specify_user:depends("redir_model", "2")
function specify_user.cfgvalue(self, section)
	return fs.readfile("/etc/ipset/gfw") or ""
end
function specify_user.write(self, section, value)
	if value then
		value = value:gsub("\r\n?", "\n")
		fs.writefile("/tmp/specify", value)
		fs.mkdir("/etc/ipset")
		if (fs.access("/etc/ipset/specify") ~= true or luci.sys.call("cmp -s /tmp/gfw /etc/ipset/specify") == 1) then
			fs.writefile("/etc/ipset/specify", value)
		end
		fs.remove("/tmp/specify")

	end
end


-- Mode: IPset
redir_ipset = r:tab("ipset", translate("Domain"))
ipset_gfw = r:taboption("ipset", Flag, "ipset_gfw", translate("GFW List"), "/etc/ipset/gfwlist")
ipset_gfw.default = "1"
ipset_gfw.rmempty = false
ipset_gfw:depends("redir_model", "3")
ipset_user = r:taboption("ipset", TextValue, "ipset_user", "User Specify Domain")
ipset_user.template = "cbi/tvalue"
ipset_user.size = 30
ipset_user.rows = 10
ipset_user.wrap = "off"
ipset_user:depends("redir_model", "3")
function ipset_user.cfgvalue(self, section)
	return fs.readfile("/etc/ipset/domain") or ""
end
function ipset_user.write(self, section, value)
	if value then
		value = value:gsub("\r\n?", "\n")
		fs.writefile("/tmp/domain", value)
		fs.mkdirr("/etc/ipset")
		if (fs.access("/etc/ipset/domain") ~= true or luci.sys.call("cmp -s /tmp/domain /etc/ipset/domain") == 1) then
			fs.writefile("/etc/ipset/domain", value)
		end
		fs.remove("/tmp/domain")
	end
end


-- LAN Access Control
lan_control = r:tab("lan_control", translate("LAN Control"))
lan_control_mode = r:taboption("lan_control", ListValue, "lan_control_mode", translate("LAN Control"))
lan_control_mode:value("0", translate("Disabled"))
lan_control_mode:value("1", translate("Allow listed only"))
lan_control_mode:value("2", translate("Allow all except listed"))
lan_control_mode.default = "0"
lan_control_mode.rmempty = false
lan_ip = r:taboption("lan_control", DynamicList, "lan_ip", translate("LAN IP"))
lan_ip.datatype = "ipaddr"


-- Socks5 Proxy
socks5 = m:section(TypedSection, "shadowsocks", translate("Socks5"))
socks5.anonymous = true
socks5_port = socks5:option(Value, "socks5_port", translate("Local Port"))
socks5_port.datatype = "port"
socks5_port.default = "10000"
socks5_port.rmempty = false

return m
